package com.jaychen.eureka.client.http;

import com.google.gson.Gson;
import com.jaychen.eureka.client.cache.LocalCache;
import com.jaychen.eureka.client.config.EurekaClientProperties;
import com.jaychen.eureka.client.domain.InstanceInfo;
import com.jaychen.eureka.client.domain.Lease;
import com.jaychen.eureka.client.result.Result;
import com.jaychen.eureka.client.util.CommonUtil;
import com.jaychen.eureka.client.util.GsonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

/**
 * eureka client 请求工具
 *
 * @Author Jay Chen
 * @Date 2020/10/26 13:10
 */
public class HttpInvokerClient {

    private static final Logger logger = LoggerFactory.getLogger(HttpInvokerClient.class);

    private EurekaClientProperties eurekaClientProperties;

    private LocalCache localCache;

    public HttpInvokerClient(EurekaClientProperties eurekaClientProperties, LocalCache localCache) {
        this.eurekaClientProperties = eurekaClientProperties;
        this.localCache = localCache;
    }

    public void heart() {
        try {
            RestTemplate restTemplate = new RestTemplate();
            //{appName}/{port}/{instanceId}/{address}/{lastDirtyTimestamp}
            String url = eurekaClientProperties.getEurekaServer()
                    + "heartBeat"
                    + "/" + eurekaClientProperties.getAppName()
                    + "/" + eurekaClientProperties.getPort()
                    + "/" + CommonUtil.getInstanceId(eurekaClientProperties.getAppName(), eurekaClientProperties.getPort())
                    + "/" + CommonUtil.getHostAddress()
                    + "/" + System.currentTimeMillis();

            HttpHeaders headers = new HttpHeaders();
            HttpMethod method = HttpMethod.POST;
            // 以表单的方式提交
            headers.setContentType(MediaType.APPLICATION_JSON);
            //将请求头部和参数合成一个请求
            HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(null, headers);
            //执行HTTP请求
            ResponseEntity<Result> response = restTemplate.exchange(url, method, requestEntity, Result.class);
            if (response.getBody().getCode() == 200) {
                return;
            }
            throw new RuntimeException("register failed" + eurekaClientProperties.getEurekaServer());
        } catch (Exception e) {
            e.printStackTrace();
            logger.info(e.getMessage(), e);
        }
    }

    /**
     * 拉取注册列表
     * /eureka/getRegistryList
     */
    public void serviceList() {

        RestTemplate restTemplate = new RestTemplate();
        String url = eurekaClientProperties.getEurekaServer()+ "getRegistryList";
        Result response = restTemplate.getForObject(url, Result.class);
        if (response.getCode() != 200) {
            throw new RuntimeException("Pull  service list failed !!!!");
        }
        if (response.getData() == null) {
            localCache.clear();
            return;
        }
        Map<String, Map<String, Lease<InstanceInfo>>> registry = GsonUtil.fromJson(GsonUtil.toJson(response.getData()), Map.class);
        localCache.replace(registry);
    }
}
